package com.glsc.ngateway.opmanage.controller.report;

import com.alibaba.fastjson.JSONObject;
import com.glsc.ngateway.common.base.domain.mysql.gateway.platform.User;
import com.glsc.ngateway.common.base.domain.mysql.opmanage.report.regulatory.RegRptCheckRulesDefine;
import com.glsc.ngateway.common.base.domain.mysql.opmanage.report.regulatory.RegRptDefine;
import com.glsc.ngateway.common.base.dto.opmanage.report.*;
import com.glsc.ngateway.common.api.common.utils.PageUtil;
import com.glsc.ngateway.opmanage.aspect.UserCache;
import com.glsc.ngateway.opmanage.service.report.RegulatoryReportService;
import com.glsc.ngateway.opmanage.utils.ZipUtils;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.util.CollectionUtils;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.File;
import java.io.IOException;
import java.math.BigInteger;
import java.net.URLEncoder;
import java.text.MessageFormat;
import java.util.*;
import java.util.stream.Collectors;

/**
 * @author: qiyr
 * @date: 2022/6/30 11:11
 * @description: 监管报表合并controller
 */
@RestController
@RequestMapping("api/regulatory")
@Api(value = "监管报表合并controller", tags = {"监管报表管理接口"})
public class RegulatoryReportController {

    private static final Logger logger = LoggerFactory.getLogger(RegulatoryReportController.class);
    private static final String MERGE_YES = "已合并";
    private static final String MSE_SEPARATOR = "<br/>";
    private static final String EXPORT_FILE_NAME = "{0}报表-{1}.zip";

    @Autowired
    private RegulatoryReportService regulatoryReportService;
    @Autowired
    private HttpServletRequest request;
    @Autowired
    private UserCache userCache;

    @GetMapping("/info")
    @ApiOperation(value = "监管报表数据合并状态查询")
    public DerivativeResponse<List<RegRptInfoDto>> info(@RequestParam("catid") String catid,
                                                        @RequestParam("bizdate") String bizdate) {
        return DerivativeResponse.success(regulatoryReportService.info(catid, bizdate));
    }

    @PostMapping("/merge")
    @ApiOperation(value = "监管报表合并")
    public DerivativeResponse<List<List>> info(@RequestBody RegRptMergeCheckDto dtoList) {
        User userDto = userCache.get(request);
        StringJoiner msg = new StringJoiner(MSE_SEPARATOR);
        msg.add("合并完成");
        List<String> idList = dtoList.getDtoList().stream().map(item -> String.valueOf(item.getId())).collect(Collectors.toList());
        return DerivativeResponse.success(msg.toString(),
                regulatoryReportService.merge(idList, dtoList.getDtoList().get(0).getBizdate(), userDto.getUsername()));
    }

    @PostMapping("/check")
    @ApiOperation(value = "监管报表合并校验")
    public DerivativeResponse<List<List>> check(@RequestBody RegRptMergeCheckDto dtoList) {
        User userDto = userCache.get(request);
        StringJoiner msg = new StringJoiner(MSE_SEPARATOR);
        msg.add("校验完成");
        // 过滤不存在校验规则、合并记录为空的记录
        List<String> idList = new ArrayList<>();
        Set<BigInteger> idSet = regulatoryReportService.getCheckRuleList().stream().map(RegRptCheckRulesDefine::getReportDefineId).collect(Collectors.toSet());
        dtoList.getDtoList().forEach(item -> {
            if (!idSet.contains(item.getId())) {
                msg.add(item.getReportName() + " 不存在校验规则，已跳过校验!");
            } else if (!CollectionUtils.isEmpty(item.getChildren()) && MERGE_YES.equals(item.getMergeStatus())) {
                idList.add(String.valueOf(item.getId()));
            } else {
                msg.add(item.getReportName() + " 合并记录为空，已跳过校验");
            }
        });

        List<List> result = regulatoryReportService.check(idList, dtoList.getDtoList().get(0).getBizdate(), userDto.getUsername());
        if (!result.isEmpty()){
            Optional<List> list = result.stream().filter(e->e.get(0).toString().equals("1")).findFirst();
            if(!list.isEmpty()){
                msg.add(list.get().get(1).toString());
                return DerivativeResponse.error(msg.toString(),result);
            }
        }
        return DerivativeResponse.success(msg.toString(),result);
    }

    @GetMapping("/check/result")
    @ApiOperation(value = "监管报表校验结果")
    public DerivativeResponse<List<JSONObject>> checkResult(@RequestParam("id") BigInteger id, @RequestParam("bizdate") String bizdate) {
        List<JSONObject> result = regulatoryReportService.getCheckResult(id, bizdate);
        for (JSONObject jsonObject : result) {
            for (Map.Entry<String, Object> entry : jsonObject.entrySet()) {
                if (entry.getValue() == null) {
                    entry.setValue("");
                    continue;
                }
                if (entry.getKey().equals("create_time")) {
                    entry.setValue(entry.getValue().toString().substring(0, 19));
                }
            }
        }
        return DerivativeResponse.success(result);
    }

    @PostMapping("/check/list")
    @ApiOperation(value = "已合并接口定义")
    public DerivativeResponse checkList(@RequestBody ExcelUploadDto dto) {
        List<RegRptDefine> result = regulatoryReportService.getMergedList(dto);
        return DerivativeResponse.success(result);
    }

    @GetMapping("/rule/list")
    @ApiOperation(value = "监管报表校验规则查询")
    public DerivativeResponse<Page<RegRptCheckRulesDefine>> rulePage(
            @ApiParam(value = "接口分类") @RequestParam("catId") String catId,
            @ApiParam(value = "页码从1开始") @RequestParam(required = false) Integer pageNo,
            @ApiParam(value = "每页显示条数 默认10") @RequestParam(required = false) Integer pageSize) {
        List<RegRptCheckRulesDefine> resultList = regulatoryReportService.getCheckRuleListByCatId(catId);
        Pageable pageable = PageRequest.of(PageUtil.initPageNo(pageNo) - 1, PageUtil.initPageSize(pageSize));
        return DerivativeResponse.success(PageUtil.listConvertToPage(resultList, pageable));
    }

    @PostMapping("/export")
    @ApiOperation(value = "监管报表导出")
    public DerivativeResponse export(@RequestBody RegRptMergeCheckDto dtoList, HttpServletResponse response) throws IOException {
        List<RegRptInfoDto> infoDtoList = dtoList.getDtoList();
        List<BiExportDto> exportDtoList = regulatoryReportService.export(infoDtoList);
        List<File> exportFileList = exportDtoList.stream().map(item -> new File(item.getFilePath())).collect(Collectors.toList());
        if (CollectionUtils.isEmpty(exportFileList)) {
            return DerivativeResponse.error("报表导出失败，文件为空或导出异常！");
        }

        // 设置文件名、类型，写入文件内容
        RegRptInfoDto infoDto = infoDtoList.get(0);
        String systemName = regulatoryReportService.getRptDefineById(infoDto.getId()).getSystemName();
        String fileName = MessageFormat.format(EXPORT_FILE_NAME, systemName, infoDto.getBizdate());
        response.setContentType("application/zip");
        response.setHeader("Content-Disposition", "attachment; filename* = utf-8''" + URLEncoder.encode(fileName, "utf-8"));
        ZipUtils.toZip(exportFileList, response.getOutputStream());
        return null;
    }

}
